package ru.usu.gv.gui.component;

import ru.usu.gv.utils.StringUtilities;

import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.JSpinner.DefaultEditor;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import java.awt.Color;
import java.awt.Dimension;
import java.util.Hashtable;

/**
 * @author spupyrev
 */
public class GVDoubleSlider extends JPanel
{
	private static final double SCALE = 100.0;
	private JSlider slider;
	private JSpinner spinner;
	private double value;

	public GVDoubleSlider(String label, double min, double max, double initValue, boolean enabled)
	{
		add(spinner = cretaeScrollBarPanel(initValue, min, max, enabled));
		setBorder(new javax.swing.border.TitledBorder(label));

		value = initValue;
		slider = new JSlider((int) (min * SCALE), (int) (max * SCALE), (int) (initValue * SCALE));
		int range = (int) ((max - min) * SCALE);
		slider.setMinorTickSpacing(range / 10);
		slider.setMajorTickSpacing(slider.getMinorTickSpacing() * 2);
		slider.setPaintLabels(true);
		slider.setPaintTicks(true);
		slider.setValue((int) (initValue * SCALE));
		Hashtable labels = slider.createStandardLabels(range / 5);
		for (Object key : labels.keySet())
		{
			Integer k = (Integer) key;
			JLabel jl = new JLabel(StringUtilities.round2(k / SCALE));
			labels.put(k, jl);
		}
		slider.setLabelTable(labels);
		add(slider);
		slider.addChangeListener(new ChangeListener()
		{
			public void stateChanged(ChangeEvent e)
			{
				if (Math.abs(slider.getValue() / SCALE - value) < 1e-8)
					return;

				setValue(slider.getValue() / SCALE);
				spinner.setValue(value);
			}
		});

		slider.setEnabled(enabled);

	}

	private JSpinner cretaeScrollBarPanel(double initValue, double min, double max, boolean enabled)
	{
		final JSpinner spinner = new JSpinner(new SpinnerNumberModel(initValue, min, max, 1.0 / SCALE));
		spinner.setEnabled(enabled);
		spinner.setPreferredSize(new Dimension(50, 20));
		spinner.addChangeListener(new ChangeListener()
		{
			public void stateChanged(ChangeEvent e)
			{
				if (Math.abs(((Number) spinner.getValue()).doubleValue() - value) < 1e-8)
					return;
				
				setValue(((Number) spinner.getValue()).doubleValue());
				slider.setValue((int) (value * SCALE));
			}
		});

		DefaultEditor editor = (DefaultEditor) spinner.getEditor();
		JFormattedTextField textField = editor.getTextField();
		textField.setEnabled(false);
		textField.setDisabledTextColor(Color.BLACK);
		textField.setHorizontalAlignment(JTextField.LEFT);

		return spinner;
	}

	public void addChangeListener(ChangeListener l)
	{
		slider.addChangeListener(l);
	}

	public double getValue()
	{
		return value;
	}

	public void setValue(double value)
	{
		this.value = value;
	}
}
